package com.wyz.saas.common.hateoas

import com.atom.api.ApiContext
import com.moczul.ok2curl.CurlInterceptor
import com.wyz.saas.common.Common
import com.wyz.saas.common.base.AbstractApiApplication
import com.wyz.saas.common.utils.JacksonUtils
import com.wyz.saas.common.utils.Logs
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory

object ApiNetwork {

    private val context: ApiContext = AbstractApiApplication.getInstance().apiContext()

    private val retrofitMap = hashMapOf<Class<*>, Any>()


    /**
     * 返回一个请求代理
     */
    fun <Api> remote(api: Class<Api>, cache: Boolean): Api {
        return remote(Common.API_URL, api, cache)
    }

    fun <Api> remote(url: String, api: Class<Api>, cache: Boolean = false): Api {
        val get = retrofitMap[api]
        if (get != null) {
            return get as Api
        }
        return retrofit(url).create(api).also {
            if (cache) {
                retrofitMap[api] = it as Any
            }
        }
    }

    // 构建一个Retrofit
    fun retrofit(url: String, vararg interceptor: Interceptor): Retrofit {
        return Retrofit
            .Builder()
            .baseUrl(url)
            .client(defaultClient(*interceptor)) // 设置client
            .addConverterFactory(JacksonConverterFactory.create(JacksonUtils.objectMapper()))// 设置Json解析器
            .build()
    }

    fun client(vararg interceptor: Interceptor): OkHttpClient {
        // 给所有的请求添加一个拦截器
        return OkHttpClient.Builder()
            .also { builder ->
                interceptor.forEach {
                    builder.addInterceptor(it)
                }
                builder.addInterceptor(CurlInterceptor { message ->
                    Logs.e(
                        String.format(
                            "Postman CURL -> \n %s \n",
                            message
                        )
                    )
                })
                builder.addNetworkInterceptor(HttpLoggingInterceptor { message ->
                    println(
                        String.format(
                            "Network Log -> \n %s \n",
                            message
                        )
                    );
                }.apply {
                    this.setLevel(HttpLoggingInterceptor.Level.BODY)
                })
            }
            .build()
    }

    fun defaultClient(vararg interceptor: Interceptor): OkHttpClient {
        // 给所有的请求添加一个拦截器
        val apis = context.getApis(Interceptor::class.java)
        val list = mutableListOf<Interceptor>()
        apis.forEach {
            list.add(it.newInstance())
        }
        if (interceptor.isNotEmpty()) {
            list.addAll(interceptor)
        }
        return client(*list.toTypedArray())
    }
}